﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using System.Windows.Input;
using personalplaner.business;
using personalplaner.business.stamm;
using personalplaner.common.mvvm;
using personalplaner.common.mvvm.commands;
using personalplaner.servicemodel.dataaccess;

namespace personalplaner.gui.stamm.viewmodels
{
	public class AddPersonToSchemaViewModel : BaseViewModel
	{
		public AddPersonToSchemaViewModel(DependencyObject parent)
			: base(parent)
		{
		}

		#region Implementation

		public override void Loaded()
		{
			var mw = GetService<IMainWindowDisplayContainer>();
			mw.IsWaitVisible = false;
		}

		#endregion

		#region Commands

		ICommand _okcommand;
		public ICommand OkCommand
		{
			get
			{
				if (_okcommand == null)
					_okcommand = new RelayCommand(OnOkCommand, CanExecuteOk);
				return _okcommand;
			}
		}

		private void OnOkCommand(object parameter)
		{
            if (IsNewPerson)
            {
                var pda = GetService<IPersonDataAccess>();
                //save new zusatzperson
                SelectedPerson.PersonTyp = business.enums.enPersonTyp.Zusatzperson;
                SelectedPerson.PrsID = pda.SavePerson(SelectedPerson, DateTime.MinValue, DateTime.MinValue, 0);
            }
            else
            {
                // check if a person with the same abteilung already exists in the plan
                var itms = from a in PlanLayout
                           where a.PrsID == SelectedPerson.PrsID && a.AbteilungID == SelectedAbteilung.AbteilungID
                           select a;

                if (!IsEmptyRow && itms.Count() > 0)
                {
                    MessageBox.Show(string.Format("Die Person {0} {1} ist bereits der Abteilung {2} zugeteilt.\nPersonen können nur einmal pro Abteilung eingeteilt werden.", SelectedPerson.Name, SelectedPerson.Nachname, SelectedAbteilung.Name),
                        "",
                        MessageBoxButton.OK,
                        MessageBoxImage.Information);
                    return;
                }
            }

			var wnd = Parent as Window;
			if (wnd == null)
				throw new Exception();
			
			wnd.DialogResult = true;
			wnd.Close();
		}

        private bool CanExecuteOk(object param)
        {
            if (!IsNewPerson && SelectedPerson != null && SelectedAbteilung != null)
                return true;

            if (IsNewPerson && SelectedPerson != null && !string.IsNullOrEmpty(SelectedPerson.Name) && !string.IsNullOrEmpty(SelectedPerson.Nachname))
                return true;

            return false;
        }

		#endregion

		#region Properties

        IEnumerable<Abteilung> _abteilungen;
        public IEnumerable<Abteilung> Abteilungen
        {
            get
            {
                return _abteilungen;
            }
            set
            {
                _abteilungen = value;
                RaisePropertyChanged("Abteilungen");

				if (_abteilungen != null && _abteilungen.Count() > 0)
					SelectedAbteilung = _abteilungen.First();
            }
        }

		Abteilung _selectedabteilungen;
		public Abteilung SelectedAbteilung
		{
			get
			{
				return _selectedabteilungen;
			}
			set
			{
				_selectedabteilungen = value;
				RaisePropertyChanged("SelectedAbteilung");
			}
		}

        IEnumerable<Person> _personen;
        public IEnumerable<Person> Personen
        {
            get
            {
                if (_personen == null)
                {
                    var da = GetService<IPersonDataAccess>();
                    _personen = da.GetPersonen(showAll: ShowAllPersonen);

					if (_personen != null && _personen.Count() > 0)
						SelectedPerson = _personen.First();

                    if (_personen != null)
                        PersonenDisplayView = CollectionViewSource.GetDefaultView(_personen);
                }
                return _personen;
            }
        }

		Person _selectedperson;
		public Person SelectedPerson
		{
			get
			{
				return _selectedperson;
			}set
			{
				_selectedperson = value;
				RaisePropertyChanged("SelectedPerson");
			}
		}

		IEnumerable<PlanSchemaItem> _planLayout;
		public IEnumerable<PlanSchemaItem> PlanLayout
		{
			get
			{
				return _planLayout;
			}
			set
			{
				_planLayout = value;
				RaisePropertyChanged("PlanLayout");
			}
		}

		bool _isEmptyRow;
		public bool IsEmptyRow
		{
			get { return _isEmptyRow; }
			set
			{
				_isEmptyRow = value;
				RaisePropertyChanged("IsEmptyRow");

                if (value)
                    IsNewPerson = false;
			}
		}

        bool _isNewPerson;
        public bool IsNewPerson
        {
            get
            {
                return _isNewPerson;
            }
            set
            {
                _isNewPerson = value;
                RaisePropertyChanged("IsNewPerson");

                if (value)
                    SelectedPerson = new Person();
            }
        }

        bool _showAllPersonen;
        public bool ShowAllPersonen
        {
            get
            {
                return _showAllPersonen;
            }
            set
            {
                _showAllPersonen = value;
                RaisePropertyChanged("ShowAllPersonen");

                _personen = null;
                RaisePropertyChanged("Personen");
            }
        }

		#endregion

        #region Filter

        string _filterString;
        public string FilterString
        {
            get
            {
                return _filterString;
            }
            set
            {
                _filterString = value;
                RaisePropertyChanged("FilterString");

                RefreshFilter();
            }
        }

        #region Implementation

        public ICollectionView PersonenDisplayView { get; set; }

        IList<Person> _displayedItems;

        /// <summary>
        /// refreshes the filtering of the combobox according to the string in <see cref="FilterString"/>
        /// </summary>
        private void RefreshFilter()
        {
            var source = PersonenDisplayView;
            if (source != null)
            {
                _displayedItems = new List<Person>();

                // remove previous filters
                //if (source.Filter != null)
                //    source.Filter -= new Predicate<object>(Filter);

                source.Filter = new Predicate<object>(Filter);

                if (_displayedItems.Count > 0)
                    SelectedPerson = _displayedItems[0];
            }
        }

        /// <summary>
        /// method that gets called by the predicate in the ICollectionView.Filter that filters the entries in the dropdown
        /// according to the string in <see cref="FilterString"/>
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        private bool Filter(object obj)
        {
            // no filter is set
            if (string.IsNullOrEmpty(FilterString))
                return true;

            // get the value from the property out of the bound object
            var value = obj as Person;
            if (value == null)
                return false;

            if (string.IsNullOrEmpty(value.Name) && string.IsNullOrEmpty(value.Nachname))
                return false;

            bool isFiltered = false;

            //bool isFiltered = value.DienstName.IndexOf(FilterString, StringComparison.CurrentCultureIgnoreCase) >= 0;
            if (!string.IsNullOrEmpty(value.Name))
                isFiltered = value.Name.IndexOf(FilterString, StringComparison.CurrentCultureIgnoreCase) >= 0;
            if (!isFiltered && !string.IsNullOrEmpty(value.Nachname))
                isFiltered = value.Nachname.IndexOf(FilterString, StringComparison.CurrentCultureIgnoreCase) >= 0;

            if (isFiltered)
                _displayedItems.Add(value);

            return isFiltered;
        }

        #endregion

        #endregion
	}
}
